﻿using System;
using System.Collections.Generic;
using System.Dynamic;
using System.Text.Json;
using System.Text.Json.Serialization;

namespace FeishuWorkflowService.Services
{
    /// <summary>
    /// 自定义ExpandoObject JSON转换器，解决动态对象序列化问题
    /// </summary>
    public class ExpandoObjectConverter : JsonConverter<ExpandoObject>
    {
        public override ExpandoObject Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
        {
            return DeserializeValue(ref reader, options) as ExpandoObject;
        }

        public override void Write(Utf8JsonWriter writer, ExpandoObject value, JsonSerializerOptions options)
        {
            SerializeValue(writer, value, options);
        }

        private object DeserializeValue(ref Utf8JsonReader reader, JsonSerializerOptions options)
        {
            switch (reader.TokenType)
            {
                case JsonTokenType.StartObject:
                    var expando = new ExpandoObject();
                    var dict = (IDictionary<string, object>)expando;

                    while (reader.Read() && reader.TokenType != JsonTokenType.EndObject)
                    {
                        if (reader.TokenType != JsonTokenType.PropertyName)
                            throw new JsonException("Expected property name");

                        string propertyName = reader.GetString();
                        reader.Read();
                        dict[propertyName] = DeserializeValue(ref reader, options);
                    }

                    return expando;

                case JsonTokenType.StartArray:
                    var list = new List<object>();

                    while (reader.Read() && reader.TokenType != JsonTokenType.EndArray)
                    {
                        list.Add(DeserializeValue(ref reader, options));
                    }

                    return list;

                case JsonTokenType.String:
                    return reader.GetString();

                case JsonTokenType.Number:
                    if (reader.TryGetInt32(out int intValue))
                        return intValue;
                    if (reader.TryGetDouble(out double doubleValue))
                        return doubleValue;
                    return reader.GetDecimal();

                case JsonTokenType.True:
                    return true;

                case JsonTokenType.False:
                    return false;

                case JsonTokenType.Null:
                    return null;

                default:
                    throw new JsonException($"Unexpected token type: {reader.TokenType}");
            }
        }

        private void SerializeValue(Utf8JsonWriter writer, object value, JsonSerializerOptions options)
        {
            if (value == null)
            {
                writer.WriteNullValue();
                return;
            }

            if (value is IDictionary<string, object> dict)
            {
                writer.WriteStartObject();
                foreach (var kvp in dict)
                {
                    writer.WritePropertyName(kvp.Key);
                    SerializeValue(writer, kvp.Value, options);
                }
                writer.WriteEndObject();
                return;
            }

            if (value is IList<object> list)
            {
                writer.WriteStartArray();
                foreach (var item in list)
                {
                    SerializeValue(writer, item, options);
                }
                writer.WriteEndArray();
                return;
            }

            // 处理基本类型
            if (value is string str)
            {
                writer.WriteStringValue(str);
            }
            else if (value is int intVal)
            {
                writer.WriteNumberValue(intVal);
            }
            else if (value is double doubleVal)
            {
                writer.WriteNumberValue(doubleVal);
            }
            else if (value is float floatVal)
            {
                writer.WriteNumberValue(floatVal);
            }
            else if (value is decimal decimalVal)
            {
                writer.WriteNumberValue(decimalVal);
            }
            else if (value is bool boolVal)
            {
                writer.WriteBooleanValue(boolVal);
            }
            else if (value is DateTimeOffset dateTimeOffset)
            {
                writer.WriteStringValue(dateTimeOffset);
            }
            else
            {
                // 对于其他类型，使用默认序列化
                JsonSerializer.Serialize(writer, value, options);
            }
        }
    }
}
